package org.an.proj.contacts.model;

import android.support.annotation.Nullable;
import java.io.Serializable;
import java.util.List;
import org.an.ku.util.StringUtil;
import org.an.proj.contacts.db.dao.ContactInfoDao;
import org.an.proj.contacts.db.dao.DaoSession;
import org.an.proj.contacts.db.dao.GroupInfoDao;
import org.an.proj.contacts.db.dao.PhoneInfoDao;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.NotNull;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
import org.greenrobot.greendao.annotation.ToOne;
import org.greenrobot.greendao.annotation.Transient;
import org.greenrobot.greendao.annotation.Unique;

/**
 * Created by Fcy on 2016/9/17.<br/>
 *
 * @Entity表示这个实体类一会会在数据库中生成对应的表
 * @Property则表示该属性将作为表的一个字段，其中nameInDb看名字就知道这个属性在数据库中对应的数据名称
 * @ToMany 定义和多个实体之间的关系。此注解适用于其他实体对象集合的字段。有三种方式可以用来实现多映射
 */
@Entity(nameInDb = "tbl_contact") public class ContactInfo implements Serializable {
  // 这个最好定义为Long, 为null时会自动增加
  @Property(nameInDb = "id") @Id(autoincrement = true) private Long id;
  /**
   * 当存储的name相同时报异常:SQLiteConstraintException: column NAME is not unique (code 19)
   */
  @NotNull /*@Unique*/ @Property(nameInDb = "name") private String name;

  /**
   * ANXIAOSHENG, 这里统一用大写，因为有些姓名直接包含大写英文字母
   */
  @Property(nameInDb = "pinyin") private String pinyin;

  /**
   * AXS
   */
  @Property(nameInDb = "jianpin") private String jianpin;

  /**
   * 姓名对应的首字母，如果不是字母则为'#'
   */
  @Property(nameInDb = "index") private String index;

  /**
   * 性别：男 1, 女 2
   */
  @Property(nameInDb = "sex") private Integer sex;

  @Property(nameInDb = "age") private Integer age;

  private String profession;
  private String address;
  private Long birthday;

  @Nullable @Property(nameInDb = "note") private String note;

  @Property(nameInDb = "groupId") private Long groupId;

  /**
   * 注意：greenDao不支持这种或者嵌套对象（因为数据库中没有这种结构），
   * 如果服务器返回的module需要嵌套对象，那么我们可以将它转为json存储到数据库
   * 添加次标记之后不会生成数据库表的列;
   * 服务器返回的数据格式；
   */
  @Transient public List<String> qqInfos;

  @Property(nameInDb = "qqInfo") private String qqInfo;

  /**
   * @ToOne 定义一对一的关系。此注解适用于其他实体对象的字段。
   * GreenDAO需要一个字段来和外联实体中的ID相对应，所以在joinProperty中制定这个字段。
   * 如果没有自定，则会自动生成一个字段。
   */
  @ToOne(joinProperty = "groupId") private GroupInfo groupInfo;

  /**
   * referencedJoinProperty:指定目标实体中与源实体相对应的外键
   */
  @ToMany(referencedJoinProperty = "contactId") private List<PhoneInfo> phones;

  // fixme 不用于建表，只用于临时存储，有没有更好的方式呢
  @Transient public List<PhoneInfo> mLocalPhones;

  /**
   * Used for active entity operations.
   */
  @Generated(hash = 1404638527) private transient ContactInfoDao myDao;
  /**
   * Used to resolve relations
   */
  @Generated(hash = 2040040024) private transient DaoSession daoSession;
  @Generated(hash = 408000349) private transient Long groupInfo__resolvedKey;

  @Generated(hash = 2019856331) public ContactInfo() {
  }

  @Generated(hash = 383031250)
  public ContactInfo(Long id, @NotNull String name, String pinyin, String jianpin, String index,
    Integer sex, Integer age, String profession, String address, Long birthday, String note,
    Long groupId, String qqInfo) {
    this.id = id;
    this.name = name;
    this.pinyin = pinyin;
    this.jianpin = jianpin;
    this.index = index;
    this.sex = sex;
    this.age = age;
    this.profession = profession;
    this.address = address;
    this.birthday = birthday;
    this.note = note;
    this.groupId = groupId;
    this.qqInfo = qqInfo;
  }

  /**
   * 将特殊字段转化已方便存储数据库
   */
  public ContactInfo transToDB() {
    qqInfo = StringUtil.stringListInvalidToString(qqInfos, ",");
    return this;
  }

  /**
   * 从数据库中读取出bean
   */
  public ContactInfo parseToBean() {
    qqInfos = StringUtil.listStringToList(qqInfo);
    return this;
  }

  /**
   * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
   * Entity must attached to an entity context.
   */
  @Generated(hash = 1942392019) public void refresh() {
    if (myDao == null) {
      throw new DaoException("Entity is detached from DAO context");
    }
    myDao.refresh(this);
  }

  /**
   * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
   * Entity must attached to an entity context.
   */
  @Generated(hash = 713229351) public void update() {
    if (myDao == null) {
      throw new DaoException("Entity is detached from DAO context");
    }
    myDao.update(this);
  }

  /**
   * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
   * Entity must attached to an entity context.
   */
  @Generated(hash = 128553479) public void delete() {
    if (myDao == null) {
      throw new DaoException("Entity is detached from DAO context");
    }
    myDao.delete(this);
  }

  /**
   * Resets a to-many relationship, making the next get call to query for a fresh result.
   */
  @Generated(hash = 2090054562) public synchronized void resetPhones() {
    phones = null;
  }

  /**
   * To-many relationship, resolved on first access (and after reset).
   * Changes to to-many relations are not persisted, make changes to the target entity.
   */
  @Generated(hash = 1554555388) public List<PhoneInfo> getPhones() {
    if (phones == null) {
      final DaoSession daoSession = this.daoSession;
      if (daoSession == null) {
        throw new DaoException("Entity is detached from DAO context");
      }
      PhoneInfoDao targetDao = daoSession.getPhoneInfoDao();
      List<PhoneInfo> phonesNew = targetDao._queryContactInfo_Phones(id);
      synchronized (this) {
        if (phones == null) {
          phones = phonesNew;
        }
      }
    }
    return phones;
  }

  public String getNote() {
    return this.note;
  }

  public void setNote(String note) {
    this.note = note;
  }

  public String getName() {
    return this.name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Long getId() {
    return this.id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getQqInfo() {
    return this.qqInfo;
  }

  public void setQqInfo(String qqInfo) {
    this.qqInfo = qqInfo;
  }

  /**
   * called by internal mechanisms, do not call yourself.
   */
  @Generated(hash = 323812056) public void __setDaoSession(DaoSession daoSession) {
    this.daoSession = daoSession;
    myDao = daoSession != null ? daoSession.getContactInfoDao() : null;
  }

  public String getAddress() {
    return this.address;
  }

  public void setAddress(String address) {
    this.address = address;
  }

  public String getProfession() {
    return this.profession;
  }

  public void setProfession(String profession) {
    this.profession = profession;
  }

  public void setBirthday(Long birthday) {
    this.birthday = birthday;
  }

  public Long getBirthday() {
    return this.birthday;
  }

  public String getJianpin() {
    return this.jianpin;
  }

  public void setJianpin(String jianpin) {
    this.jianpin = jianpin;
  }

  public String getPinyin() {
    return this.pinyin;
  }

  public void setPinyin(String pinyin) {
    this.pinyin = pinyin;
  }

  /** called by internal mechanisms, do not call yourself. */
  @Generated(hash = 817018617) public void setGroupInfo(GroupInfo groupInfo) {
    synchronized (this) {
      this.groupInfo = groupInfo;
      groupId = groupInfo == null ? null : groupInfo.getId();
      groupInfo__resolvedKey = groupId;
    }
  }

  /** To-one relationship, resolved on first access. */
  @Generated(hash = 416695722) public GroupInfo getGroupInfo() {
    Long __key = this.groupId;
    if (groupInfo__resolvedKey == null || !groupInfo__resolvedKey.equals(__key)) {
      final DaoSession daoSession = this.daoSession;
      if (daoSession == null) {
        throw new DaoException("Entity is detached from DAO context");
      }
      GroupInfoDao targetDao = daoSession.getGroupInfoDao();
      GroupInfo groupInfoNew = targetDao.load(__key);
      synchronized (this) {
        groupInfo = groupInfoNew;
        groupInfo__resolvedKey = __key;
      }
    }
    return groupInfo;
  }

  public Long getGroupId() {
    return this.groupId;
  }

  public void setGroupId(Long groupId) {
    this.groupId = groupId;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  public void setSex(Integer sex) {
    this.sex = sex;
  }

  public String getIndex() {
    return this.index;
  }

  public void setIndex(String index) {
    this.index = index;
  }

  public Integer getSex() {
    return this.sex;
  }

  public Integer getAge() {
    return this.age;
  }

  //	/**
  //	 * joinProperty: 对于复杂一点的关系可以定义一组@JoinProperty注解。
  //	 * 每个@JoinProperty注解都需要有源实体中的源属性和对应实体中的引用属性。
  //	 */
  //	@ToMany(joinProperties = {
  //		@JoinProperty(name = "", referencedName = "")
  //	})

  //	/**
  //	 * @JoinEntity 在做NM多对多映射的时候使用
  //	 */
  //	@ToMany
  //	@JoinEntity(
  //		entity = QQInfo.class,
  //		sourceProperty = "",
  //		targetProperty = ""
  //	)

  @Override public String toString() {
    return "ContactInfo{"
      + "name='"
      + name
      + '\''
      + ", profession='"
      + profession
      + '\''
      + ", address='"
      + address
      + '\''
      + ", birthday="
      + birthday
      + ", note='"
      + note
      + '\''
      + ", groupId="
      + groupId
      + ", qqInfo='"
      + qqInfo
      + '\''
      + '}';
  }
}
